package com.example.campus.page_controller.support;



import com.example.campus.page_controller.dto.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.subject.Subject;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.ui.Model;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @desc:  全局捕获Controller层的出现的异常。
 * @author: Ping
 * @author lyt0628
 * @date: 2024/10/22 17:04
 */

@Configuration
@ControllerAdvice
@Slf4j
public class WebExceptionHandler {


    /**
     * Validation 异常处理
     * @param e
     * @return
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ResponseResult<Object> handleAllException(MethodArgumentNotValidException e) {
        log.error(e.getMessage());
        Map fieldErrMap = new HashMap();
        e.getBindingResult().getFieldErrors().forEach((errObj)->{
            fieldErrMap.put(errObj.getField(),errObj.getDefaultMessage());
        });

        return ResponseResult.error(
                HttpStatus.BAD_REQUEST,
                "Request Values is invalid",
                fieldErrMap);
    }


    /**
     * 处理 Shiro Access 异常
     **/
    @ExceptionHandler(AuthorizationException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public String handleException(AuthorizationException e, Model model) {

        log.debug("AuthorizationException was thrown", e);

        Map<String, Object> map = new HashMap<>();

        map.put("status", HttpStatus.FORBIDDEN.value()); // HTTP状态码
        map.put("message", "No message available"); // 错误信息
        model.addAttribute("errors", map); // 封装到ModelAndVIew

        return "error";
    }

    /**
     * 提供 Shiro 当前用户
     * @return
     */
    @ModelAttribute(name = "subject")
    public Subject subject() {
        return SecurityUtils.getSubject();
    }


    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult<Object> handleAllException(AuthorizationException e) {
        log.error(e.getMessage());
        return ResponseResult.error(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
    }

}
